/****

    activequant - activestocks.eu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

	
	contact  : contact@activestocks.eu
    homepage : http://www.activestocks.eu

****/
package org.activequant.core.domainmodel.data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.activequant.core.domainmodel.SeriesSpecification;
import org.activequant.core.types.TimeStamp;
import org.activequant.core.types.Tuple;
import org.activequant.util.exceptions.ValueNotFoundException;
import org.activequant.util.tools.ArrayUtils;



/**
 * A TimeSeries(ArrayList subclass) whose elements are Quote objects.<br/>
 * Holds the following inherited/associated variables:
 * <ul>
 * <li>id(Long)</li>
 * <li>seriesSpecification(SeriesSpecification)</li>
 * <li>inherited list of elements (List&lt;Quote&gt;)</li>
 * </ul>
 * <b>History:</b><br>
 *  - [08.07.2007] Created (Ulrich Staudinger)<br>
 *  - [23.06.2007] moved to new domain model (Erik Nijkamp)<br>
 *  - [05.08.2007] Fixed clone() (Erik Nijkamp)<br>
 *  - [28.09.2007] removed baseclass, removed instrumentspec (Erik Nijkamp)<br>
 *  - [28.09.2007] moved to new domain model (Erik Nijkamp)<br>
 *  - [06.11.2007] moved generic functionality to TimeSeries<T> (Erik Nijkamp)<br>
 *
 *  @author Ulrich Staudinger
 *  @author Erik Nijkamp
 */
public class QuoteSeries extends TimeSeries<Quote> implements Serializable {

	private static final long serialVersionUID = -3722093387498618030L;
	
    /**
     * an empty QuoteSeries constructor.
     */
    public QuoteSeries() {
    	
    }

    /**
     * constructs  a QuoteSeries(ArrayList and TimeSeries subclass) using the given quotes(List&lt;Quote&gt;) to set its Quote elements.
     * @param list
     */
    public QuoteSeries(List<Quote> quotes) {
    	super(quotes);
    }
    /**
     * Constructs a QuoteSeries(ArrayList and TimeSeries subclass) using the given spec(SeriesSpecification) and quotes(List&lt;Quote&gt;) to set its associated 
	 * seriesSpecification(SeriesSpecification) and its Quote elements.
     * @param spec
     * @param quotes
     */
    public QuoteSeries(SeriesSpecification spec, List<Quote> quotes) {
    	super(quotes);
    	setSeriesSpecification(spec);
    }
    
    
    /**
     * constructs a QuoteSeries(ArrayList and TimeSeries subclass) using the given quotes(Quote...) to set its Quote elements.
     * @param candles
     */
    public QuoteSeries(Quote... quotes) {
    	this(ArrayUtils.asList(quotes));
    }
    /**
     * Constructs a QuoteSeries(ArrayList and TimeSeries subclass) using the given spec(SeriesSpecification) and quotes(Quote...) to set its associated 
	 * seriesSpecification(SeriesSpecification) and its Quote elements.
     * @param spec
     * @param quotes
     */
    public QuoteSeries(SeriesSpecification spec, Quote... quotes) {
    	this(quotes);
    	setSeriesSpecification(spec);
    }
    /**
     * Sets the elements of this QuoteSeries(ArrayList and TimeSeries subclass) with the given quotes(Quote...).
     * @param quotes
     */
    public void setQuotes(Quote... quotes) {
    	setQuotes(ArrayUtils.asList(quotes));
    }
    /**
     * Sets the elements of this QuoteSeries(ArrayList and TimeSeries subclass) with the given quotes(List&lt;Quote&gt;).
     * @param quotes
     */
    public void setQuotes(List<Quote> quotes) {
    	clear();
    	addAll(quotes);
    }
    /**
     * returns a Quote[] array containing the elements of this QuoteSeries(ArrayList and TimeSeries subclass)
     * @return
     */
    public Quote[] getQuotes() {
    	return ArrayUtils.asArray(this, Quote.class);
    }
	
    /**
     * clone this QuoteSeries instance.
     * @return cloned object
     */
	public QuoteSeries clone() {
		Quote[] clonedQuotes = new Quote[size()];
		Quote[] quotes = toArray(new Quote[]{});
		for(int i = 0; i < quotes.length; i++) {
			clonedQuotes[i] = quotes[i].clone();
		}
		QuoteSeries clone = new QuoteSeries(seriesSpecification, clonedQuotes);
		return clone;
	}
	/**
	 * returns a QuoteSeries containing the Quote elements whose TimeStamps are within(inclusive) the given start-end(TimeStamp) interval
	 */
    public QuoteSeries getTimeFrame(TimeStamp start, TimeStamp end) {
    	return (QuoteSeries) super.getTimeFrame(start, end);
    }
	/**
	 * returns a QuoteSeries containing the Quote elements within(inclusive) the given start-end(int) index interval
	 */
	public QuoteSeries subList(int start, int end) throws ValueNotFoundException {
		return (QuoteSeries) super.subList(start, end);
	}
	/**
	 * returns a QuoteSeries containing the Quote elements whose TimeStamps are within(inclusive) the given start-end(TimeStamp) interval
	 */
	public QuoteSeries subList(TimeStamp start, TimeStamp end) throws ValueNotFoundException {
		return (QuoteSeries) super.subList(start, end);
	}
	
	/**
	 * returns the ask price series of this quote series.<br/>
	 * returns a List&lt;Tuple&lt;TimeStamp, Double&gt;&gt; containing the timeStamp-askPrice pairs of the Quote elements whose askPrice(double) is set
	 * @return
	 */
	public List<Tuple<TimeStamp, Double>> getAskPriceSeries() {
		List<Tuple<TimeStamp, Double>> ret = new ArrayList<Tuple<TimeStamp, Double>>();
		for(Quote q : this){
			if(q.getAskPrice()!=Quote.NOT_SET){
				ret.add(new Tuple<TimeStamp, Double>(q.getTimeStamp(), q.getAskPrice()));
			}
		}
		return ret; 
	}
	
	/**
	 * returns the bid price series of this quote series. 
	 * @return
	 */
	public List<Tuple<TimeStamp, Double>> getBidPriceSeries() {
		List<Tuple<TimeStamp, Double>> ret = new ArrayList<Tuple<TimeStamp, Double>>();
		for(Quote q : this){
			if(q.getBidPrice()!=Quote.NOT_SET){
				ret.add(new Tuple<TimeStamp, Double>(q.getTimeStamp(), q.getBidPrice()));
			}
		}
		return ret; 
	}
	/**
	 * returns a double[] array containing the askPrice(double) of every Quote element
	 * @return
	 */
    public double[] getAskPrices() {
        double[] doubles = new double[size()];
        int idx = 0;
        for (Quote q : this) {
        	doubles[idx++] = q.getAskPrice();
        }
        return doubles;
    }
    /**
     * returns a double[] array containing the bidPrice(double) of every Quote element
     * @return
     */
    public double[] getBidPrices() {
        double[] doubles = new double[size()];
        int idx = 0;
        for (Quote q : this) {
        	doubles[idx++] = q.getBidPrice();
        }
        return doubles;
    }
	/**
	 * sets the askPrice(double) of every Quote element with a value from the given doubles(double[])
	 * @param doubles
	 */
    public void setAskPrices(double[] doubles) {
    	assert(doubles.length == size()) : "length invalid";
    	for(int i = 0; i < size(); i++) {
    		get(i).setAskPrice(doubles[i]);
    	}
    }
    /**
     * sets the bidPrice(double) of every Quote element with a value from the given doubles(double[])
     * @param doubles
     */
    public void setBidPrices(double[] doubles) {
    	assert(doubles.length == size()) : "length invalid";
    	for(int i = 0; i < size(); i++) {
    		get(i).setBidPrice(doubles[i]);
    	}
    }
	
}